//-------------------------------------------------------------------------------------
// <copyright file="BizTalkInstallation.cs" company="Microsoft">
//      Copyright (c) 2003 Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <summary>
//      Helper class for managing BizTalk using System.Management.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.BizTalk2004.Configuration
{
	#region Using directives

	using System;
	using System.Globalization;
	using System.Management;

	#endregion

	/// <summary>
	/// Helper class for managing BizTalk using <see cref="System.Management"/>.
	/// </summary>
	internal sealed class ManagementHelper
	{
		#region Constants

		/// <summary>
		/// The class name for the BizTalk deployment service, which is <b>MSBTS_DeploymentService</b>.
		/// </summary>
		public const string DeploymentServiceClassName = "MSBTS_DeploymentService";

		/// <summary>
		/// The class name for the BizTalk host, which is <b>MSBTS_Host</b>.
		/// </summary>
		public const string HostClassName = "MSBTS_Host";

		/// <summary>
		/// The class name for a BizTalk host instance setting, which is <b>MSBTS_HostInstanceSetting</b>.
		/// </summary>
		public const string HostInstanceSettingClassName = "MSBTS_HostInstanceSetting";

		/// <summary>
		/// The class name for a BizTalk host setting, which is <b>MSBTS_HostSetting</b>.
		/// </summary>
		public const string HostSettingClassName = "MSBTS_HostSetting";

		/// <summary>
		/// The class name for a BizTalk server host, which is <b>MSBTS_ServerHost</b>.
		/// </summary>
		public const string ServerHostClassName = "MSBTS_ServerHost";

		/// <summary>
		/// The class name for a BizTalk server host, which is <b>MSBTS_HostInstance</b>.
		/// </summary>
		public const string HostInstanceClassName = "MSBTS_HostInstance";

		#endregion

		#region Constructors

		/// <summary>
		/// Has only static members so cannot be instantiated.
		/// </summary>
		private ManagementHelper()
		{
		}

		#endregion

		#region Static Methods

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementClass"/> representing the class MSBTS_DeploymentService.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management class for.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementClass"/>.
		/// </returns>
		public static ManagementClass GetDeploymentServiceClass(BizTalkInstallation installation)
		{
			return ManagementHelper.GetManagementClass(installation, ManagementHelper.DeploymentServiceClassName);
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementClass"/> representing the class MSBTS_Host.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management class for.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementClass"/>.
		/// </returns>
		public static ManagementClass GetHostClass(BizTalkInstallation installation)
		{
			return ManagementHelper.GetManagementClass(installation, ManagementHelper.HostClassName);
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementClass"/> representing the class MSBTS_ServerHost.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management class for.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementClass"/>.
		/// </returns>
		public static ManagementClass GetServerHostClass(BizTalkInstallation installation)
		{
			return ManagementHelper.GetManagementClass(installation, ManagementHelper.ServerHostClassName);
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementClass"/> representing the class MSBTS_ServerHost.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management class for.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementClass"/>.
		/// </returns>
		public static ManagementClass GetHostInstanceClass(BizTalkInstallation installation)
		{
			return ManagementHelper.GetManagementClass(installation, ManagementHelper.HostInstanceClassName);
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementObject"/> representing a particular MSBTS_Host.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management object for.
		/// </param>
		/// <param name="hostName">
		/// The name of the host.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementObject"/>.
		/// </returns>
		public static ManagementObject GetHostObject(BizTalkInstallation installation, string hostName)
		{
			ManagementScope scope = ManagementHelper.GetManagementScope(installation);
			string queryString = string.Format(CultureInfo.InvariantCulture, "select * from {0} where name = '{1}'", ManagementHelper.HostClassName, hostName);
			ObjectQuery query = new ObjectQuery(queryString);
			ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query, null);
			ManagementObjectCollection objects = searcher.Get();
			if (objects.Count == 0)
			{
				throw new ArgumentException("The host does not exist or could not be found.", "hostName");
			}
			//have to enumerate to get the item out, as the collection does not have an indexer
			ManagementObject hostObject = null;
			foreach (ManagementObject obj in objects)
			{
				hostObject = obj;
				break;
			}
			return hostObject;
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementClass"/> representing the class MSBTS_HostInstanceSetting.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management class for.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementClass"/>.
		/// </returns>
		public static ManagementClass GetHostInstanceSettingClass(BizTalkInstallation installation)
		{
			return ManagementHelper.GetManagementClass(installation, ManagementHelper.HostInstanceSettingClassName);
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementClass"/> representing the class MSBTS_HostSetting.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management class for.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementClass"/>.
		/// </returns>
		public static ManagementClass GetHostSettingClass(BizTalkInstallation installation)
		{
			return ManagementHelper.GetManagementClass(installation, ManagementHelper.HostSettingClassName);
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementObject"/> representing a particular MSBTS_HostSetting.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management object for.
		/// </param>
		/// <param name="hostSettingName">
		/// The name of the host setting.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementObject"/>.
		/// </returns>
		public static ManagementObject GetHostSettingObject(BizTalkInstallation installation, string hostSettingName)
		{
			ManagementScope scope = ManagementHelper.GetManagementScope(installation);
			string queryString = string.Format(CultureInfo.InvariantCulture, "select * from {0} where name = '{1}'", ManagementHelper.HostSettingClassName, hostSettingName);
			ObjectQuery query = new ObjectQuery(queryString);
			ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query, null);
			ManagementObjectCollection objects = searcher.Get();
			if (objects.Count == 0)
			{
				throw new ArgumentException("The host setting does not exist or could not be found.", "hostName");
			}
			//have to enumerate to get the item out, as the collection does not have an indexer
			ManagementObject hostSettingObject = null;
			foreach (ManagementObject obj in objects)
			{
				hostSettingObject = obj;
				break;
			}
			return hostSettingObject;
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementClass"/> for a specified class name.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management class for.
		/// </param>
		/// <param name="className">
		/// The name of the WMI class, e.g. MSBTS_DeploymentService.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementClass"/>.
		/// </returns>
		public static ManagementClass GetManagementClass(BizTalkInstallation installation, string className)
		{
			ManagementScope scope = ManagementHelper.GetManagementScope(installation);
			ManagementPath path = new ManagementPath(className);
			ManagementClass obj = new ManagementClass(scope, path, null);
			obj.Get();
			return obj;
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementObject"/> for a specified object path.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the management object for.
		/// </param>
		/// <param name="objectPath">
		/// The object path for the WMI object, e.g. MSBTS_Host.Name = 'HostName'.
		/// </param>
		/// <returns>
		/// A <see cref="System.Management.ManagementObject"/>.
		/// </returns>
		public static ManagementObject GetManagementObject(BizTalkInstallation installation, string objectPath)
		{
			ManagementScope scope = ManagementHelper.GetManagementScope(installation);
			ManagementPath path = new ManagementPath(objectPath);
			ManagementObject obj = new ManagementObject(scope, path, null);
			obj.Get();
			return obj;
		}

		/// <summary>
		/// Gets a <see cref="System.Management.ManagementScope"/> for the root\MicrosoftBizTalkServer namespace.
		/// </summary>
		/// <param name="installation">
		/// The BizTalk installation to get the scope for.
		/// </param>
		/// <returns>
		/// A connected <see cref="System.Management.ManagementScope"/>.
		/// </returns>
		public static ManagementScope GetManagementScope(BizTalkInstallation installation)
		{
			//this cause problems on multi-server BTS installs.  This code is being executed on the server which host the 
			//BTS engine but the value of installation.Server is the DB server instance where the BizTalk Management DB is stored
			//The database server will not contain the BizTalk WMI namespace required for deploying BTS object - this is only
			//installed on the server(s) with the BTS engine components.
			// string scopePath = string.Format(CultureInfo.InvariantCulture, @"\\{0}\root\MicrosoftBizTalkServer", installation.Server);
			
			//Instead, connect to the current machine's MicrosoftBizTalkServer WMI namespace to perform the actions.
			string scopePath = @"root\MicrosoftBizTalkServer";

			ManagementScope scope = new ManagementScope(scopePath);
			scope.Options.EnablePrivileges = true;
			scope.Options.Impersonation = ImpersonationLevel.Impersonate;
			scope.Connect();
			return scope;
		}

		#endregion
	}
}

